package com.ys.service.sys.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bo.dto.NameValueDto;
import com.bo.dto.NameValueSelectDto;
import com.bo.util.StringUtil;
import com.ys.constant.AppConstant;
import com.ys.dto.DtreeDto;
import com.ys.entity.base.Tables;
import com.ys.entity.sys.SysCol;
import com.ys.entity.sys.SysMenu;
import com.ys.enume.sys.SysMenuEnum;
import com.ys.mapper.sys.SysColMapper;
import com.ys.mapper.sys.SysMapper;
import com.ys.mapper.sys.SysMenuMapper;
import com.ys.service.sys.SysMenuService;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;
import com.ys.vo.W;


@Service("sysMenuService")
public class SysMenuServiceImpl implements SysMenuService {

	@Autowired
	private SysColMapper sysColMapper;
	@Autowired
	private SysMenuMapper sysMenuMapper;
	@Autowired
	private SysMapper sysMapper;
	

	@Override
	public LayuiTableVoJA list() {
		
//		List<Menu> listMap = menuMapper.queryList(2);
//
//		String jsonStr = JSON.toJSONStringWithDateFormat(listMap, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat);
//		JSONArray JA = JSON.parseArray(jsonStr);
		
		LayuiTableVoJA vo = new LayuiTableVoJA();
		
//		vo.setData(JA);
//        vo.setCount(listMap.size());
        return vo;
	}

	@Override
	public DtreeDto dtree(Integer maxLevel) {
		
		if (maxLevel == null) {
			maxLevel = 999;
		}
		
		DtreeDto.StatusDto status = DtreeDto.StatusDto.init(200, "");

		List<DtreeDto.DataDto> data = new ArrayList<DtreeDto.DataDto>();
		List<SysMenu> listMenuLev = new SysMenu().setOrderby("A.lev asc, A.sort_no asc").queryList();
		// 一级菜单
		for(SysMenu sysMenu1 : listMenuLev) {
			if (sysMenu1.getLev() != SysMenuEnum.Lev.ONE.value) {
				continue;
			}
			Long id1 = sysMenu1.getId();
			String title1 = sysMenu1.getName();
			Long parentId1 = sysMenu1.getPid();
			
			// 二级菜单
			List<DtreeDto.DataDto> children = new ArrayList<DtreeDto.DataDto>();
			for (SysMenu sysMenu2 : listMenuLev) {
				if (sysMenu2.getLev() != SysMenuEnum.Lev.TWO.value || sysMenu2.getPid().longValue() != sysMenu1.getId().longValue()) {
					continue;
				}
				Long id2 = sysMenu2.getId();
				String title2 = sysMenu2.getName();
				Long parentId2 = sysMenu2.getPid();
				
				// 三级菜单
				List<DtreeDto.DataDto> children1 = new ArrayList<DtreeDto.DataDto>();
				for (SysMenu sysMenu3 : listMenuLev) {
					if (sysMenu3.getLev() != SysMenuEnum.Lev.THREE.value || sysMenu3.getPid().longValue() != sysMenu2.getId().longValue()) {
						continue;
					}
					Long id3 = sysMenu3.getId();
					String title3 = sysMenu3.getName();
					Long parentId3 = sysMenu3.getPid();
					List<DtreeDto.DataDto> children2 = null;
					DtreeDto.DataDto dto = new DtreeDto.DataDto(id3, title3, parentId3, DtreeDto.DataDto.initCheckArr(null), children2);
					children1.add(dto);
				}
				
				DtreeDto.DataDto dataDto2 = new DtreeDto.DataDto(id2, title2, parentId2, DtreeDto.DataDto.initCheckArr(null), children1);
				children.add(dataDto2);
			}
			
			DtreeDto.DataDto dataDto1 = new DtreeDto.DataDto(id1, title1, parentId1, DtreeDto.DataDto.initCheckArr(null), children);
			data.add(dataDto1);
		}
		return new DtreeDto(status, data);
	}

	@Override
	public R addOneMenu(String name) {
		
		// 验证名称
		if (name == null || name.length() == 0) {
			return R.error("菜单名称不能为空");
		}
		
		// 获取最大的排序序号
		SysMenu menuMax = new SysMenu().setLev(SysMenuEnum.Lev.ONE.value).setOrderby("A.sort_no desc").queryFirst();
		Integer sortNo = menuMax == null ? 0 : menuMax.getSortNo() + 1;
		
		Long pid = 0L;
		String nameTable = null;
		Integer lev = SysMenuEnum.Lev.ONE.value;
		Integer templetType = null;
		String templetPath = null;
		String databaseTable = null;
		String nameShiroAuth = null;
		Long flowModelId = null;
		String pathGridRequest = null;
		String pathGridEditRequest = null;
		String pathGridExportRequest = null;
		String pathCommitAdd = null;
		String pathCommitEdit = null;
		String pathCommitDelete = null;
		String pathFlowPass = null;
		String pathFlowRefuse = null;
		Long subGridId = null;
		String icon = null;
		
		SysMenu sysMenu = SysMenu.sysMenu(pid, lev, templetType, templetPath, nameTable, databaseTable, sortNo, nameShiroAuth, flowModelId, pathGridRequest, pathGridEditRequest, pathGridExportRequest, pathCommitAdd, pathCommitEdit, pathCommitDelete, pathFlowPass, pathFlowRefuse, subGridId, icon, 1);
		
		sysMenuMapper.insert(sysMenu);
		
		return R.ok();
	}

	@Override
	public R addTwoMenu(Long pid, String name) {
		
		// 验证pid
		if (pid == null) {
			return R.error("所属菜单ID不能为空");
		} else if (new SysMenu().setId(pid).setLev(SysMenuEnum.Lev.ONE.value).count() == 0) {
			return R.error("所属菜单不存在");
		}
		
		// 验证名称
		if (name == null || name.length() == 0) {
			return R.error("菜单名称不能为空");
		}
		
		// 获取最大的排序序号
		SysMenu menuMax = new SysMenu().setPid(pid).setLev(SysMenuEnum.Lev.TWO.value).setOrderby("A.sort_no desc").queryFirst();
		Integer sortNo = menuMax == null ? 0 : menuMax.getSortNo() + 1;

		String nameTable = null;
		Integer lev = SysMenuEnum.Lev.ONE.value;
		Integer templetType = null;
		String templetPath = null;
		String databaseTable = null;
		String nameShiroAuth = null;
		Long flowModelId = null;
		String pathGridRequest = null;
		String pathGridEditRequest = null;
		String pathGridExportRequest = null;
		String pathCommitAdd = null;
		String pathCommitEdit = null;
		String pathCommitDelete = null;
		String pathFlowPass = null;
		String pathFlowRefuse = null;
		Long subGridId = null;
		String icon = null;
		
		SysMenu sysMenu = SysMenu.sysMenu(pid, lev, templetType, templetPath, nameTable, databaseTable, sortNo, nameShiroAuth, flowModelId, pathGridRequest, pathGridEditRequest, pathGridExportRequest, pathCommitAdd, pathCommitEdit, pathCommitDelete, pathFlowPass, pathFlowRefuse, subGridId, icon, 1);
		
		sysMenuMapper.insert(sysMenu);
		
		return R.ok();
	}

	@Override
	public R addThreeMenu(Long pid, String name, String nameTable, Integer typeTemplet,
			Integer isCheckbox, Integer isShowNo, Integer isShowCount) {
		
		// 验证pid
		if (pid == null) {
			return R.error("所属菜单ID不能为空");
		} else if (new SysMenu().setId(pid).setLev(SysMenuEnum.Lev.TWO.value).count() == 0) {
			return R.error("所属菜单不存在");
		}
		
		// 验证名称
		if (name == null || name.length() == 0) {
			return R.error("菜单名称不能为空");
		}
		
		// 验证类型
		if (typeTemplet == null) {
			return R.error("类型不能为空");
		}
		
		// 验证表名
		if (nameTable == null || nameTable.length() == 0) {
			return R.error("表名不能为空");
		}
		
		// 获取最大的排序序号
		SysMenu menuMax = new SysMenu().setPid(pid).setLev(SysMenuEnum.Lev.THREE.value).setOrderby("A.sort_no desc").queryFirst();
		Integer sortNo = menuMax == null ? 0 : menuMax.getSortNo() + 1;

		Integer lev = SysMenuEnum.Lev.THREE.value;
		Integer templetType = null;
		String templetPath = null;
		String databaseTable = null;
		String nameShiroAuth = AppConstant.NAME_SHIRO_AUTH.replace("RP_NAME", StringUtil.replaceUnderlineAndfirstToUpper(nameTable));
		Long flowModelId = null;
		String pathGridRequest = AppConstant.URL_GRID.replace("RP_NAME", StringUtil.replaceUnderlineAndfirstToUpper(nameTable));
		String pathGridEditRequest = null;
		String pathGridExportRequest = null;
		String pathCommitAdd = null;
		String pathCommitEdit = null;
		String pathCommitDelete = null;
		String pathFlowPass = null;
		String pathFlowRefuse = null;
		Long subGridId = null;
		String icon = null;
		
		SysMenu sysMenu = SysMenu.sysMenu(pid, lev, templetType, templetPath, nameTable, databaseTable, sortNo, nameShiroAuth, flowModelId, pathGridRequest, pathGridEditRequest, pathGridExportRequest, pathCommitAdd, pathCommitEdit, pathCommitDelete, pathFlowPass, pathFlowRefuse, subGridId, icon, 1);
		sysMenuMapper.insert(sysMenu);
		
		return R.ok();
	}
	
	public static void main(String[] args) {
		String nameTable = "ys_operate_company";
		System.out.println( AppConstant.NAME_SHIRO_AUTH.replace("RP_NAME", StringUtil.replaceUnderlineAndfirstToUpper(nameTable)));
	}

	@Override
	@Transactional
	public R resort(String sysMenuArr) {
		JSONArray menuJA = JSON.parseArray(sysMenuArr);
		
		for (int i = 0; i < menuJA.size(); i++) {
			JSONObject menuJO = menuJA.getJSONObject(i);
			Long id = menuJO.getLong("id");
			Integer sortNo = i + 1;
			sysMapper.updateMenuOfSortNo(id, sortNo);
		}
		return R.ok();
	}

	@Override
	public String toAddTwoMenu(Model model, Long pid) {
		
		if (pid == null) {
			return W.error(model, "PID不能为空");
		}
		
		SysMenu sysMenu = new SysMenu().setId(pid).queryFirst();
		
		String pName = sysMenu.getName();
		ToAddTwoMenuDto dto = new ToAddTwoMenuDto(pid, pName);
		model.addAttribute("dto", dto);
		
		return "sys/sysMenu/toAddTwoMenu";
	}

	@Override
	public String toAddThreeMenu(Model model, Long pid) {
		
		if (pid == null) {
			return W.error(model, "PID不能为空");
		}
		
		SysMenu sysMenu = new SysMenu().setId(pid).queryFirst();
		
		//加载关联表名
		List<Tables> tableList = new Tables().where("TABLE_SCHEMA = '" + AppConstant.DATABASE_NAME + "'").queryList();
		
		// 菜单类型数组
		List<NameValueSelectDto> typeTempletArr = new ArrayList<NameValueSelectDto>();
		for(SysMenuEnum.TypeTemplet e : SysMenuEnum.TypeTemplet.values()) {
			String name = e.name;
			String value = e.value.toString();
			boolean seleted = false;
			typeTempletArr.add(new NameValueSelectDto(name, value, seleted));
		}
		
		String pName = sysMenu.getName();
		List<NameValueDto> tableNameArr = new ArrayList<NameValueDto>();
		for(Tables table : tableList) {
			String name = table.getTableName() + table.getTableComment();
			String value = table.getTableName();
			tableNameArr.add(new NameValueDto(name, value));
		}
		ToAddThreeMenuDto dto = new ToAddThreeMenuDto(pid, pName, typeTempletArr, tableNameArr);
		model.addAttribute("dto", dto);
		return "sys/sysMenu/toAddThreeMenu";
	}

	@Override
	public String toResort(Model model, Long pid) {
		
		if (pid == null) {
			return W.error(model, "上级菜单ID不能为空");
		}
		
		List<SysMenu> listSysMenu = new SysMenu().setPid(pid).setOrderby("A.sort_no asc").queryList();;
		
		List<ToResortDto.RowDto> rows = new ArrayList<ToResortDto.RowDto>();
		for(SysMenu menu : listSysMenu) {
			Long id = menu.getId();
			String name = menu.getName();
			rows.add(new ToResortDto.RowDto(id, name));
		}
		
		ToResortDto dto = new ToResortDto(pid, rows);
		model.addAttribute("dto", dto);
		return "sys/sysMenu/toResort";
	}
	
	@Override
	@Transactional
	public R threeMenuInitCol(
			Long menuId,
			String colArr) throws Exception {
		
		if (menuId == null) {
			return R.error("菜单ID不能为空");
		}
		
		// 处理字段
		JSONArray colJA = JSON.parseArray(colArr);
		// 字段的编码-名称MAP，用于遍历是否存在
		Map<String, String> codeNameMap = new HashMap<String, String>();
		for(int i = 0; i < colJA.size(); i++) {
			JSONObject colJO = colJA.getJSONObject(i);
			codeNameMap.put(colJO.getString("value"), colJO.getString("title"));
		}
		// 过滤数据库中的数据
		List<SysCol> listSysCol = new SysCol().setMenuId(menuId).queryList();
		for(SysCol sysCol : listSysCol) {
			// 已存在，跳过不处理
			if (codeNameMap.containsKey(sysCol.getCode())) {
				codeNameMap.remove(sysCol.getCode());
				continue;
			} else {
				sysColMapper.deleteTrue(sysCol.getId());
			}
		}
		
		// 过滤后的字段
		for(Map.Entry<String, String> entry : codeNameMap.entrySet()) {
			String code = entry.getKey();
			String name = "";
			if (code.equals("createTime")) {
				name = "创建时间";
			} else if (code.equals("updateTime")) {
				name = "更新时间";
			} else if (code.equals("status")) {
				name = "状态";
			} else {
				name = entry.getValue().replace("（" + entry.getKey() + "）", "");
			}
			
			Integer sortNo = 1;
			Integer authType = 1;
			String frontType = "t_text";
			Integer frontEdit = 0;
			Integer frontShow = 0;
			Integer frontWidth = 80;
			Integer frontFixed = 0;
			Integer frontAlign = 0;
			Integer frontConditionState = 0;
			String frontConditionType = "t_text";
			String frontConditionRangeType = "t_text";
			String frontConditionCode = null;
			String frontConditionDefault = null;
			String dictKeyBase = null;
			Integer formLength = 80;
			Integer formAddState = 0;
			String formAddType = "t_text";
			Integer formAddRequired = 0;
			Integer formAddReadonly = 0;
			Integer formAddHidden = 0;
			Integer formEditState = 0;
			String formEditType = "t_text";
			Integer formEditRequired = 0;
			Integer formEditReadonly = 0;
			Integer formEditHidden = 0;
			Integer importState = 0;
			Integer importSortNo = 0;
			String modalKey = null;
			String modalRelativeCode = null;
			String modalValueCode = null;
			String dropdownRequestPath = null;
			Integer multyFileSourceType = null;
			
			SysCol entity = SysCol.sysCol(menuId, name, code, sortNo, authType,
					frontType, frontEdit, frontShow, frontWidth, frontFixed, frontAlign, frontConditionState, frontConditionType, frontConditionRangeType, frontConditionCode, frontConditionDefault, dictKeyBase,
					formLength, formAddState, formAddType, formAddRequired, formAddReadonly, formAddHidden, formEditState, formEditType, formEditHidden, formEditRequired, formEditReadonly,
					importState, importSortNo, modalKey, modalRelativeCode, modalValueCode, dropdownRequestPath, multyFileSourceType, 1);
			
			if (sysColMapper.insert(entity) != 1) {
				throw new RuntimeException("失败");
			}
		}
		
		return R.ok();
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) {
		if (id == null) {
			return R.error("菜单ID不能为空");
		}
		
		if (new SysMenu().setPid(id).count() > 0) {
			return R.error("还有子菜单，不能删除");
		}
		
		SysMenu sysMenu = new SysMenu().setId(id).queryFirst();
		if (sysMenu == null) {
			return R.error("菜单不存在");
		}
		
		if (sysMenu.getLev() == SysMenuEnum.Lev.THREE.value) {
			
			// 删除字段（表格）
			sysMapper.deleteTrueSysColTableBySysMenuId(id);
			// 删除字段（搜索）
			sysMapper.deleteTrueSysColSearchBySysMenuId(id);
			// 删除字段（总）
			sysMapper.deleteTrueSysColByMenuId(id);
			
			// 删除角色按钮
			sysMapper.deleteTrueSysRoleButtonBySysMenuId(id);
			
			// 删除按钮
			sysMapper.deleteTrueSysButtonByMenuId(id);
			
			// 删除角色-菜单
			sysMapper.deleteTrueSysRoleMenuBySysMenuId(id);
			
			// 删除菜单
			sysMenuMapper.deleteTrue(id);
		} else {
			
			// 删除菜单
			sysMenuMapper.deleteTrue(id);
		}
		
		
		return R.ok();
	}

	@Override
	public R editSysMenu(Long id, String name, String nameShiroAuth) {
		
		// 验证id
		if (id == null) {
			return R.error("菜单ID不能为空");
		}
		
		// 验证名称
		if (name == null || name.length() == 0) {
			return R.error("菜单名称不能为空");
		}
		
		SysMenu entity = new SysMenu().setId(id).queryFirst();
		
		entity.setName(name)
			.setNameShiroAuth(nameShiroAuth);
		
		sysMenuMapper.update(entity);
		
		return R.ok("操作成功");
	}

	@Override
	public R editSysMenuFormBase(Long id, String pathPageAdd, String pathPageEdit, String pathCommitAdd, String pathCommitEdit) {
		
		// 验证id
		if (id == null) {
			return R.error("菜单ID不能为空");
		}
		
		SysMenu entity = new SysMenu().setId(id).queryFirst();
		
		if (entity.getLev() != SysMenuEnum.Lev.THREE.value) {
			return R.error("不是三级菜单，无需设置");
		}
		
		entity.setPathCommitAdd(pathCommitAdd)
			.setPathCommitEdit(pathCommitEdit);
		
		sysMenuMapper.update(entity);
		
		return R.ok("操作成功");
	}

	@Override
	public String toEditSysMenu(Model model, Long id, Integer tabIndex) {
		tabIndex = tabIndex != null ? tabIndex : 1;
		
		SysMenu sysMenu = new SysMenu().setId(id).queryFirst();
		if (sysMenu.getLev() != SysMenuEnum.Lev.THREE.value && tabIndex > 1) {
			return W.error(model, "只有三级菜单才能设置更多信息！");
		}
		
		// 查找总字段，设置MAP，方便寻找
		List<SysCol> listSysCol = new SysCol().setMenuId(id).queryList();
		Map<Long, SysCol> MAP_SysCol = new HashMap<Long, SysCol>();
		for(SysCol sysCol : listSysCol) {
			MAP_SysCol.put(sysCol.getId(), sysCol);
		}
		
		String name = sysMenu.getName();
		String nameShiroAuth = sysMenu.getNameShiroAuth();
		String pathCommitAdd = sysMenu.getPathCommitAdd(); // 新增页提交地址
		String pathCommitEdit = sysMenu.getPathCommitEdit(); // 修改页提交地址
		ToEditSysMenuDto dto = new ToEditSysMenuDto(id, name, nameShiroAuth, tabIndex, pathCommitAdd, pathCommitEdit);
		
		model.addAttribute("dto", dto);
		
		return "sys/sysMenu/toEditSysMenu";
	}
}
